﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Globalization;
using Billing.DataObjects;
using System.Data.Linq;


namespace Billing.Windows.Shell
{
    public class ConverterBase
    {
        public ConverterBase()
        {
            ShellDataContext shellDataContext = new ShellDataContext();
            foreach (FontMapping item in shellDataContext.FontMappings)
            {
                this.FontList.Add(item.Name, item.ABC);
            }
        }

        FontConverter fc = new FontConverter(false);
        public SortedList<string, string> FontList = new SortedList<string, string>();
        public event BeforeConvertHandler BeforeConvert;
        public event ConvertHandler Convert;
        public event AfterConvertHandler AfterConvert;

        public void ChangeFontExcel(bool CheckFont, string FontFrom, string FontTo)
        {
            string CellValue;
            int PBValue = 0;

            object objExcel = Marshal.GetActiveObject("Excel.Application");

            object oSelectedCells = GetVallue<object>(objExcel, "Selection", null);

            object oColumns = GetVallue<object>(oSelectedCells, "Columns", null);
            object oRows = GetVallue<object>(oSelectedCells, "Rows", null);

            int ColumnsCount = GetVallue<int>(oColumns, "Count", null);
            int RowsCount = GetVallue<int>(oRows, "Count", null);

            try
            {
                SetVallue(objExcel, "ScreenUpdating", new object[] { false });
                object oCurrentCell = null;

                fc.FontTo = this.FontList[FontTo];
                fc.FontFrom = this.FontList[FontFrom];

                if (this.BeforeConvert != null)
                    this.BeforeConvert(GetVallue<int>(oSelectedCells, "Count", null));

                for (int i = 1; i < ColumnsCount + 1; i++)
                {
                    for (int n = 1; n < RowsCount + 1; n++)
                    {
                        oCurrentCell = GetVallue<object>(oSelectedCells, "Cells", new object[] { n, i });
                        CellValue = GetVallue<string>(oCurrentCell, "Text", null);

                        object oCellFont = GetVallue<object>(oCurrentCell, "Font", null);
                        string CellFontName = GetVallue<string>(oCellFont, "Name", null);

                        PBValue += 1;
                        if (CheckFont)
                        {
                            if (this.FontList.ContainsKey(CellFontName))
                            {
                                fc.FontFrom = this.FontList[CellFontName];

                                SetVallue(oCurrentCell, "Value2", new object[] { fc.Convert(CellValue) });
                                SetVallue(oCellFont, "Name", new object[] { FontTo });
                            }
                            else
                                SetVallue(oCellFont, "ColorIndex", new object[] { 3 });
                        }
                        else
                        {
                            SetVallue(oCurrentCell, "Value2", new object[] { fc.Convert(CellValue) });
                            SetVallue(oCellFont, "Name", new object[] { FontTo });
                        }
                        System.Windows.Forms.Application.DoEvents();

                        if (this.Convert != null)
                            this.Convert(PBValue);
                    }
                }
                SetVallue(objExcel, "ScreenUpdating", new object[] { true });
                SetVallue(objExcel, "Visible", new object[] { true });

                if (this.AfterConvert != null)
                    this.AfterConvert();

                Marshal.ReleaseComObject(objExcel);

                objExcel = null;
                GC.GetTotalMemory(true);
            }
            catch (Exception)
            {

                throw;
            }
        }

        public void SetVallue(object obj, string PropertyName, object[] args)
        {
            obj.GetType().InvokeMember(PropertyName, BindingFlags.SetProperty, null, obj, args, CultureInfo.InstalledUICulture);

        }
        public T GetVallue<T>(object obj, string PropertyName, object[] args)
        {
            object o = obj.GetType().InvokeMember(PropertyName, BindingFlags.GetProperty, null, obj, args, CultureInfo.InstalledUICulture);
            if (o is System.DBNull)
                return default(T);
            else
                return (T)o;

        }
    }

    public delegate void BeforeConvertHandler(int MaxValue);
    public delegate void ConvertHandler(int Value);
    public delegate void AfterConvertHandler();
}
